﻿using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
using System.Security.Cryptography;
using System.Text;


namespace SimpleORM.Extensions.RSAKeyAlgorithm
{
    /// <summary>
    /// RSA对称加密算法
    /// </summary>
    public class RSAKeyConverter
    {
        /// <summary>
        /// 私钥xml转base64
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <returns></returns>
        public string FromXmlPrivateKey(string xmlPrivateKey)
        {
            string result = string.Empty;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(xmlPrivateKey);
                RSAParameters param = rsa.ExportParameters(true);
                RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(
                    new BigInteger(1, param.Modulus), new BigInteger(1, param.Exponent),
                    new BigInteger(1, param.D), new BigInteger(1, param.P),
                    new BigInteger(1, param.Q), new BigInteger(1, param.DP),
                    new BigInteger(1, param.DQ), new BigInteger(1, param.InverseQ));
                PrivateKeyInfo privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);

                result = Convert.ToBase64String(privateKey.ToAsn1Object().GetEncoded());
            }
            return result;
        }

        /// <summary>
        /// 公钥xml转base64
        /// </summary>
        /// <param name="xmlPublicKey"></param>
        /// <returns></returns>
        public string FromXmlPublicKey(string xmlPublicKey)
        {
            string result = string.Empty;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(xmlPublicKey);
                RSAParameters p = rsa.ExportParameters(false);
                RsaKeyParameters keyParams = new RsaKeyParameters(
                    false, new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent));
                SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyParams);
                result = Convert.ToBase64String(publicKeyInfo.ToAsn1Object().GetEncoded());
            }
            return result;
        }

        /// <summary>
        /// 私钥base64转xml私钥
        /// </summary>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        public string ToXmlPrivateKey(string privateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParams =
                PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)) as RsaPrivateCrtKeyParameters;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                RSAParameters rsaParams = new RSAParameters()
                {
                    Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned(),
                    Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned(),
                    D = privateKeyParams.Exponent.ToByteArrayUnsigned(),
                    DP = privateKeyParams.DP.ToByteArrayUnsigned(),
                    DQ = privateKeyParams.DQ.ToByteArrayUnsigned(),
                    P = privateKeyParams.P.ToByteArrayUnsigned(),
                    Q = privateKeyParams.Q.ToByteArrayUnsigned(),
                    InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned()
                };
                rsa.ImportParameters(rsaParams);
                return rsa.ToXmlString(true);
            }
        }

        /// <summary>
        ///私钥base64转xml公钥
        /// </summary>
        /// <param name="pubilcKey"></param>
        /// <returns></returns>
        public string ToXmlPublicKey(string pubilcKey)
        {
            RsaKeyParameters p =
                PublicKeyFactory.CreateKey(Convert.FromBase64String(pubilcKey)) as RsaKeyParameters;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                RSAParameters rsaParams = new RSAParameters
                {
                    Modulus = p.Modulus.ToByteArrayUnsigned(),
                    Exponent = p.Exponent.ToByteArrayUnsigned()
                };
                rsa.ImportParameters(rsaParams);
                return rsa.ToXmlString(false);
            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="xmlPublicKey"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string RSAEncrypt(string xmlPublicKey, string content)
        {
            string encryptedContent = string.Empty;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(xmlPublicKey);
                byte[] encryptedData = rsa.Encrypt(Encoding.Default.GetBytes(content), false);
                encryptedContent = Convert.ToBase64String(encryptedData);
            }
            return encryptedContent;
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string RSADecrypt(string xmlPrivateKey, string content)
        {
            string decryptedContent = string.Empty;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(xmlPrivateKey);
                byte[] decryptedData = rsa.Decrypt(Convert.FromBase64String(content), false);
                decryptedContent = Encoding.GetEncoding("gb2312").GetString(decryptedData);
            }
            return decryptedContent;
        }
    }
}


//Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

//RSASecretKey rSASecretKey= new ();

//var key = rSASecretKey.GenerateRSASecretKey();

//string xmlPublicKey = key.PublicKey;
//string xmlPrivateKey = key.PrivateKey;

//string strPublicKey= rSAKeyConverter.FromXmlPublicKey(xmlPublicKey);
//string strPrivateKey= rSAKeyConverter.FromXmlPrivateKey(xmlPrivateKey);


//Console.WriteLine("strPublicKey:\n" + strPublicKey);
//Console.WriteLine("\n");
//Console.WriteLine("strPrivateKey:\n" + strPrivateKey);

//string s1 = rSAKeyConverter.ToXmlPublicKey(strPublicKey);
//string s2 = rSAKeyConverter.ToXmlPrivateKey(strPrivateKey);

//string str = "987654321";
//string s1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApg9RFzYXGht1KeTnkF7Sip60SOZZGI8xjkaBtGIP4xjky2/jiGF2uI3YzN4CPpdNAhFfUrgzlPjwbLr1ryq+oJOQbwep0SPMbSZusM4YRK9Rq6aZc6f6xU5Oej0tiNsNJ2z4TLh2rb1NlCxhiI7B4j2jQMmesfkkr5zoDGEzn/D94zDyu8Bf/mq+cEihL/S0e0UBzwYQhuoozuwSbcNY6kp5nsjeF/uQxUiM9BnGtsqkjBUwlwNjKq6LeCSDSQz/GdE4XFjTwzYPOfLJR12/kelasR0EmSFxpIGVds66C5/YGQ3H78bQOIXRXAorVKSQ3RsALOqcsQSQcG4rKwCB2QIDAQAB";
//string str = "25e84405-c1ad-46c5-a80e-7b2d0a63c8a9";;

//string s33 = rSAKeyConverter.RSAEncrypt(rSAKeyConverter.ToXmlPublicKey(s1), str);


//Console.WriteLine(s33);
//string s3 = rSAKeyConverter.RSAEncrypt(s1, str);
////string s4= rSAKeyConverter.RSADecrypt(s2, s3);



//Console.WriteLine("\n");
////Console.WriteLine(str);
////Console.WriteLine("\n");
//Console.WriteLine(s3);